package com.zkyt.lib_msdk_ext.component.camera

import android.util.Log
import com.geoai.mavlink.geoainet.payload.enums.CameraNV2StreamSource
import com.geoai.mavlink.geoainet.payload.enums.CameraNV3StreamSource
import com.geoai.mavlink.geoainet.payload.enums.CameraThermalPalette
import com.geoai.mavlink.geoainet.payload.enums.CameraZoomRatio
import com.geoai.mavlink.geoainet.payload.interfaces.INV2CameraListener
import com.zkyt.lib_msdk_ext.common.CallbackWithRxHandler
import com.zkyt.lib_msdk_ext.common.SDKExtUtil
import com.zkyt.lib_msdk_ext.component.AbsSDKExt
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import java.util.Optional

/**
 * Created by chenyu on 2024/1/19
 * Description:
 */
class NV2CameraExt: AbsSDKExt<INV2CameraListener>(), IRealCameraExt, IAdvancedCameraExt {

    private var nv2Camera: INV2CameraListener? = null

    override fun init(originManager: INV2CameraListener) {
        nv2Camera = originManager
    }

    override fun destroy() {
        super.destroy()
        nv2Camera = null
    }

    override fun getOriginManager(): INV2CameraListener? {
        return nv2Camera
    }

    fun setCameraSourceRx(source: CameraNV2StreamSource): Completable {
        return Completable.create { emitter ->
            nv2Camera?.setCameraSource(source) {
                SDKExtUtil.handleError(emitter, it)
            }
        }
    }

    fun getCameraSourceRx(): Single<CameraNV2StreamSource> {
        return Single.create { single->
            nv2Camera?.getCameraSource(CallbackWithRxHandler(single))?:let {
                single.onError(Throwable("nv2Camera is null"))
            }
        }
    }

    /**
     * 循环主动get camera source。
     *
     * @return
     * @deprecated 其实CameraZoom也可以通过[BaseCameraExt.getCaptureInfoObservable]中的推送获取.
     * 这里做一个循环get的例，避免有的字段没有推送
     */
    fun getCameraSourceObservable(): Observable<Optional<CameraNV2StreamSource>> {
        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getCameraSourceRx)
    }

    fun getCameraZoomRatioRx(): Single<CameraZoomRatio> {
        return Single.create {
            nv2Camera?.getCameraZoomRatio(CallbackWithRxHandler(it))
        }
    }

    /**
     * 循环主动get zoom ratio
     *
     * @return
     *
     * @deprecated 其实CameraZoom也可以通过[BaseCameraExt.getCaptureInfoObservable]中的推送获取.
     * 这里做一个循环get的例，避免有的字段没有推送
     */
    fun getCameraZoomRatioObservable(): Observable<Optional<CameraZoomRatio>> {
        // todo 加todo引起警觉，注释，前往别使用下面注释这种方式了，固件目前的协议架构不支持短时间连续发送同一个的命令
        // 如果断时间有多个监听者多次getxxxObservable，会导致后面的getxxx会失败。
        /** 请使用[getAutoGetSubject] */
//        return Observable.interval(INTERVAL_GET, TimeUnit.MILLISECONDS)
//            .flatMapSingle {
//                getCameraZoomRatioRx()
//            }.subscribeOn(Schedulers.io())

        val curMethod = object : Any() {}.javaClass.enclosingMethod
        return autoGetProcessor.getAutoGetSubject(curMethod, this::getCameraZoomRatioRx)
    }

    fun setCameraZoomRatioRx(ratio: CameraZoomRatio): Completable {
        return Completable.create { emitter ->
            nv2Camera?.setCameraZoomRatio(ratio) {
                SDKExtUtil.handleError(emitter, it)
            }
        }
    }

    fun singleShootRx(source: CameraNV2StreamSource): Completable {
        return Completable.create { emitter ->
            nv2Camera?.startSingleCapture(source) {
                SDKExtUtil.handleError(emitter, it)
            }
        }
    }
}